Skip to content

Tweak implicit resolution #6034

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 8, 2019

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Mar 6, 2019

I have noted that the "more implicit parameters first" rule when applied
unconditionally can lead to implicit search explosion. The test case is
i3430.scala:

println(Nil.min) // error: ambiguous

We need to find an Ordering[T] for uninstantiated T. Before implicit arguments were taken
into account we'd try two types (in this case Long and BigInteger) and get an ambiguity. Then
we'd check whether any of the other candidates would dominate both of these types, which was
not the case. So, we are done with an ambiguity.

But when implicit arguments were taken into account there are many types that still are better
then these. E.g.

[T1: Ordering, T2: Ordering]: Ordering[(T1, T2)]

and so on far all other supported arities of Ordering for tuples! So one of these has to be tried.
That leads to searches for other uninstantiated orderings and so on. Running i3430.scala by hand,
I got a compiler hang. I am not sure why the test suite succeeded nevertheless; there must be
something surprising going on in the tests.

My fix to get round this issue is that now implicit parameters are only considered if the result
types of two alternatives are unifiable. Hopefully, that's not too constraining.

odersky added 2 commits March 6, 2019 19:13
I have noted that the "more implicit parameters first" rule when applied
unconditionally can lead to implicit search explosion. The test case is
i3430.scala:

    println(Nil.min) // error: ambiguous

We need to find an `Ordering[T]` for uninstantiated `T`. Before implicit arguments were taken
into account we'd try two types (in this case Long and BigInteger) and get an ambiguity. Then
we'd check whether any of the other candidates would dominate both of these types, which was
not the case. So, we are done with an ambiguity.

But when implicit arguments were taken into account there are many types that still are better
then these. E.g.

    [T1: Ordering, T2: Ordering]: Ordering[(T1, T2)]

and so on far all other supported arities of Ordering for tuples! So one of these has to be tried.
That leads to searches for other uninstantiated orderings and so on. Running i3430.scala by hand,
I got a compiler hang. I am not sure why the test suite succeeded nevertheless; there must be
something surprising going on in the tests.

My fix to get round these issue is that now implicit parameters are only considered if the result
types of two alternatives are unifiable. Hopefully, that's not too constraining.
@odersky
Copy link
Contributor Author

odersky commented Mar 7, 2019

I solved the mystery why the neg/i3430.scala test was passing previously. We got:

-- Error: /Users/odersky/workspace/dotty/tests/neg/i3430.scala:3:9 -----------------------------------------------------
3 |  println(Nil.min) // error: no implicit found
  |         ^
  |         Recursion limit exceeded.
  |         Maybe there is an illegal cyclic reference?
  |         If that's not the case, you could also try to increase the stacksize using the -Xss JVM option.
  |         A recurring operation is (inner to outer):
  |         
  |           subtype Long <:< T
  |           subtype Ordering[Long] <:< Ordering[T]
  |           subtype scala.math.Ordering.Long.type <:< Ordering[T]
one error found

This PR contains a check file i3430.check that guards against relapsing in this way.

@odersky odersky requested a review from smarter March 7, 2019 14:42
@odersky odersky requested a review from milessabin March 7, 2019 16:14
@odersky
Copy link
Contributor Author

odersky commented Mar 8, 2019

I have to merge this now as it blocks other PRs. We should continue to brainstorm about better solutions.

@odersky odersky merged commit 6efb61b into scala:master Mar 8, 2019
@allanrenucci allanrenucci deleted the fix-implicit-resolution branch March 8, 2019 19:05
smarter added a commit to dotty-staging/dotty that referenced this pull request Mar 8, 2019
Looks like scala#6034 and scala#6040 collided resulting in a CI failure on
master.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants